package com.example.demo.core.lang;

import com.example.demo.core.util.XmlUtil;
import org.springframework.util.ClassUtils;

import java.io.FileInputStream;
import java.io.IOException;

/**
 * @author yujie
 */
public class MyClassLoader extends ClassLoader {

    private final String classPath;

    private final String packName;

    public MyClassLoader() {
        System.out.println(ClassUtils.getDefaultClassLoader().getResource("").getPath());
        this.classPath = ClassUtils.getDefaultClassLoader().getResource("").getPath();
        this.packName = XmlUtil.getPomModel().getGroupId();
    }

    public MyClassLoader(String classPath) {
        this.classPath = classPath;
        this.packName = XmlUtil.getPomModel().getGroupId();
    }

    public MyClassLoader(String classPath, String packName) {
        this.classPath = classPath;
        this.packName = packName;
    }


    @Override
    public Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
        synchronized (getClassLoadingLock(name)) {
            Class<?> c = findLoadedClass(name);
            if (c == null) {
                if (name.startsWith(packName)) {
                    //如果目录以我定义的开始，则用我的
                    c = findClass(name);
                } else {
                    //如果不是我开始的文件，则用父类classloader
                    c = this.getParent().loadClass(name);
                }
            }
            if (resolve) {
                resolveClass(c);
            }
            return c;
        }
    }

    @Override
    protected Class<?> findClass(String className) {
        byte[] data = loadByte(className);
        return defineClass(className, data, 0, data.length);
    }


    private byte[] loadByte(String className) {
        className = className.replaceAll("\\.", "/");
        StringBuilder stringBuilder = new StringBuilder(classPath);
        stringBuilder.append(className).append(".class");
        FileInputStream inputStream = null;
        byte[] data;
        try {
            inputStream = new FileInputStream(stringBuilder.toString());
            data = new byte[inputStream.available()];
            inputStream.read(data);
            return data;
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return null;
    }

    public String getPackName() {
        Package pack = getClass().getPackage();
        String packName = pack.getName();
        do {
            packName = packName.substring(0, packName.lastIndexOf("."));
            pack = Package.getPackage(packName);
        } while (null != pack);
        return packName;
    }
}
